package com.whfc.common.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @Description:
 * @author: xugcheng
 * @version: 1.0
 * @date: 2019/7/17 15:12
 */
public class DateUtil {

    private static Logger logger = LoggerFactory.getLogger(DateUtil.class);

    public static final String DATE_FORMAT = "yyyy-MM-dd";

    public static final String MONTH_FORMAT = "yyyy-MM";

    public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    public static final String TIME_FORMAT = "HH:mm:ss";

    public static final String UTC_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";

    public static final String DATE_1_FORMAT = "yyyy/MM/dd";

    /**
     * 格式化日志
     *
     * @param date
     * @param dateFormat
     * @return
     */
    public static String formatDate(Date date, String dateFormat) {
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        return sdf.format(date);
    }

    public static String formatDateTime(Date date) {
        return formatDate(date, DATE_TIME_FORMAT);
    }

    public static String formatDate(Date date) {
        return formatDate(date, DATE_FORMAT);
    }

    public static Date getDateTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date getDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 解析日期
     *
     * @param dateStr
     * @param dateFormat
     * @return
     * @throws ParseException
     */
    public static Date parseDate(String dateStr, String dateFormat) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
            return sdf.parse(dateStr);
        } catch (ParseException ex) {
            logger.error("dateStr:{},dateFormat:{}", dateStr, dateFormat);
            logger.error("日期解析失败", ex);
        }
        return null;
    }

    public static Date parseDateTime(String dateStr) {
        return parseDate(dateStr, DATE_TIME_FORMAT);
    }


    /**
     * 设置时间为当月第一天
     *
     * @param time
     * @return
     */
    public static Date getMonthBegin(Date time) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 设置时间为当月第一天
     *
     * @param timeStr （为"2019-09" 格式的字符串）
     * @return
     */
    public static Date getMonthBegin(String timeStr) {

        Date time = parseDate(timeStr, MONTH_FORMAT);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 设置时间为当月最后一天
     *
     * @param time
     * @return
     */
    public static Date getMonthEnd(Date time) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        return calendar.getTime();
    }

    /**
     * 设置时间为当月的最后一天
     *
     * @param timeStr（格式为"2019-07" 的字符串）
     * @return
     */
    public static Date getMonthEnd(String timeStr) {
        Date time = parseDate(timeStr, MONTH_FORMAT);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        return calendar.getTime();
    }

    public static Date getYearEnd(int year) {
        Calendar cal = Calendar.getInstance();
        // 设置年份
        cal.set(Calendar.YEAR, year);
        // 设置月份
        cal.set(Calendar.MONTH, Calendar.DECEMBER);
        // 获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        // 设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        // 设置时间
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 0);
        Date date = cal.getTime();
        return date;
    }

    public static Date getYearBegin(int year) {
        Calendar cal = Calendar.getInstance();
        // 设置年份
        cal.set(Calendar.YEAR, year);
        // 设置月份
        cal.set(Calendar.MONTH, Calendar.JANUARY);
        // 设置日期
        cal.set(Calendar.DAY_OF_MONTH, 1);
        // 设置时间
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        Date date = cal.getTime();
        return date;
    }

    /**
     * 获取一天的开始
     *
     * @param time
     * @return
     */
    public static Date getDateBegin(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static LocalDateTime getDateTimeBegin(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime().toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
    }

    /**
     * 获取一天开始的时间
     *
     * @param timeStr（格式为"2019-09-11" 的字符串）
     * @return
     */
    public static String getDateBegin(String timeStr) {
        Date time = parseDate(timeStr, DATE_FORMAT);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return formatDate(calendar.getTime(), DATE_TIME_FORMAT);
    }

    /**
     * 获取一天的结束
     *
     * @param time
     * @return
     */
    public static Date getDateEnd(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取一天的结束
     *
     * @param time
     * @return
     */
    public static LocalDateTime getDateTimeEnd(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime().toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
    }

    /**
     * 获取一天的结束时间
     *
     * @param timeStr（格式为"2019-08-11"的字符串）
     * @return
     */
    public static String getDateEnd(String timeStr) {
        Date time = parseDate(timeStr, DATE_FORMAT);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 0);
        return formatDate(calendar.getTime(), DATE_TIME_FORMAT);
    }


    /**
     * 增加月份
     *
     * @param date
     * @param month
     * @return
     */
    public static Date addMonth(Date date, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);
        date = calendar.getTime();
        return date;
    }


    public static Date addWeek(Date date, int week) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.WEEK_OF_YEAR, week);
        date = calendar.getTime();
        return date;
    }


    /**
     * 增加天数
     *
     * @param date
     * @param days
     * @return
     */
    public static Date addDays(Date date, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, days);
        date = calendar.getTime();
        return date;
    }

    /**
     * 增加小时
     *
     * @param date
     * @param hours
     * @return
     */
    public static Date addHours(Date date, int hours) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, hours);
        date = calendar.getTime();
        return date;
    }

    /**
     * 增加分钟
     *
     * @param date
     * @param minutes
     * @return
     */
    public static Date addMinutes(Date date, int minutes) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minutes);
        date = calendar.getTime();
        return date;
    }

    /**
     * 增加秒数
     *
     * @param date
     * @param seconds
     * @return
     */
    public static Date addSeconds(Date date, int seconds) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, seconds);
        date = calendar.getTime();
        return date;
    }

    /**
     * 获取星期
     *
     * @param date
     * @return
     */
    public static int getDayOfWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_WEEK);
    }

    public static List<Date> getDateListBetween(Date startDate, Date endDate) {
        Date date = getDateBegin(startDate);
        List<Date> dateList = new ArrayList<>();
        while (date.getTime() <= endDate.getTime()) {
            dateList.add(date);
            date = addDays(date, 1);
        }
        return dateList;
    }

    public static List<Date> getMonthListByYear(int year) {
        List<Date> monthList = new ArrayList<>();
        for (int i = 0; i < 12; i++) {
            Calendar cal = Calendar.getInstance();
            // 设置年份
            cal.set(Calendar.YEAR, year);
            // 设置月份
            cal.set(Calendar.MONTH, i);
            // 设置日期
            cal.set(Calendar.DAY_OF_MONTH, 1);
            cal.set(Calendar.HOUR_OF_DAY, 0);
            cal.set(Calendar.MINUTE, 0);
            cal.set(Calendar.SECOND, 0);
            cal.set(Calendar.MILLISECOND, 0);
            Date date = cal.getTime();
            monthList.add(date);
        }
        return monthList;
    }

    /**
     * 获取两个时间间的小时
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public static List<Date> getHourListBetween(Date startTime, Date endTime) {
        List<Date> hourList = new ArrayList<>();
        while (startTime.getTime() <= endTime.getTime()) {
            startTime = addHours(startTime, 1);
            hourList.add(startTime);
        }
        return hourList;
    }


    /**
     * 获取两个时间之间的所有月份
     *
     * @param minDate
     * @param maxDate
     * @return
     * @throws ParseException
     */
    public static List<String> getMonthBetween(Date minDate, Date maxDate) throws ParseException {
        ArrayList<String> result = new ArrayList<String>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月

        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();

        min.setTime(minDate);
        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

        max.setTime(maxDate);
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

        Calendar curr = min;
        while (curr.before(max)) {
            result.add(sdf.format(curr.getTime()));
            curr.add(Calendar.MONTH, 1);
        }

        return result;
    }

    /**
     * 获取两个时间之间的所有月份
     *
     * @param minDate
     * @param maxDate
     * @return
     * @throws ParseException
     */
    public static List<Date> getMonthNoDayBetween(Date minDate, Date maxDate) {
        ArrayList<Date> result = new ArrayList<Date>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月

        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();

        min.setTime(minDate);
        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

        max.setTime(maxDate);
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

        Calendar curr = min;
        while (curr.before(max)) {
            result.add(curr.getTime());
            curr.add(Calendar.MONTH, 1);
        }

        return result;
    }

    /**
     * 获取两个月份之间的月份
     *
     * @param minDate
     * @param maxDate
     * @return
     */
    public static List<Date> getMonthListBetween(Date minDate, Date maxDate) {
        Date date = getDateBegin(minDate);
        List<Date> dateList = new ArrayList<>();
        while (date.getTime() <= maxDate.getTime()) {
            dateList.add(date);
            date = addMonth(date, 1);
        }
        return dateList;
    }

    /**
     * 获取当前时间的上周天日期
     *
     * @param time
     * @return Sun Aug 04 23:59:59 CST 2019
     */
    public static Date getLastSunday(Date time) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 0);
        int dayWeek = calendar.get(Calendar.DAY_OF_WEEK);

        if (dayWeek == 1) {
            dayWeek = 8;
        }

        calendar.add(Calendar.DATE, calendar.getFirstDayOfWeek() - dayWeek);
        calendar.add(Calendar.DATE, 4 + calendar.getFirstDayOfWeek());
        Date sundayDate = calendar.getTime();
        Date lastSunday = addDays(sundayDate, -7);
        return lastSunday;
    }


    /**
     * 获取当前时间的上周一日期
     *
     * @param time
     * @return Mon Jul 29 00:00:00 CST 2019
     */
    public static Date getLastMonday(Date time) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        int dayWeek = calendar.get(Calendar.DAY_OF_WEEK);
        if (dayWeek == 1) {
            dayWeek = 8;
        }

        calendar.add(Calendar.DATE, calendar.getFirstDayOfWeek() - dayWeek);
        Date mondayDate = calendar.getTime();
        Date lastMonday = addDays(mondayDate, -7);
        return lastMonday;
    }

    /**
     * 获取月份的所有天
     *
     * @param date
     * @return
     */
    public static List<Date> getDayListOfMonth(Date date) {
        List<Date> list = new ArrayList<>();
        Calendar aCalendar = Calendar.getInstance();
        aCalendar.setTime(date);
        int year = aCalendar.get(Calendar.YEAR);//年份
        int month = aCalendar.get(Calendar.MONTH) + 1;//月份
        int day = aCalendar.getActualMaximum(Calendar.DATE);
        for (int i = 1; i <= day; i++) {
            String aDate = String.valueOf(year) + "-" + month + "-" + i;
            Date parseDate = parseDate(aDate, "yyyy-MM-dd");
            list.add(parseDate);
        }
        return list;
    }

    /**
     * 获取两个时间每间隔多少分钟范围类所有的时间
     *
     * @param minDate
     * @param maxDate
     * @param minute
     * @return
     */
    public static List<Date> getDayListOfMinute(Date minDate, Date maxDate, Integer minute) {
        List<Date> list = new ArrayList<>();
        Date date = minDate;
        while (date.getTime() < maxDate.getTime()) {
            list.add(date);
            date = addMinutes(date, minute);
        }
        return list;
    }


    /**
     * 获取时间范围内的所有天
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 获取时间范围内的所有天
     */
    public static List<Date> getDayList(Date startDate, Date endDate) {
        if (startDate == null || endDate == null || (endDate.getTime() <= startDate.getTime())) {
            return new ArrayList<>();
        }
        endDate = getDateBegin(endDate);
        List<Date> list = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        startDate = getDateBegin(startDate);
        calendar.setTime(startDate);
        do {
            list.add(calendar.getTime());
            calendar.add(Calendar.DAY_OF_MONTH, 1);
        } while (calendar.getTime().getTime() <= endDate.getTime());
        return list;
    }

    /**
     * 获取两个时间相差的天数
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return
     */
    public static int getDaysBettweenDate(Date startDate, Date endDate) {
        int days = (int) ((endDate.getTime() - startDate.getTime()) / (1000 * 3600 * 24)) + 1;
        return days;
    }

    /**
     * 获取两个时间相差的天数 取绝对值
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 天数
     */
    public static int getDateSpace(Date startDate, Date endDate) {
        return Math.abs(getDateSpaceWithNotAbs(startDate, endDate));
    }

    /**
     * 获取两个时间相差的天数
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 天数
     */
    public static int getDateSpaceWithNotAbs(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            return 0;
        }
        startDate = clearTime(startDate);
        endDate = clearTime(endDate);
        return (int) ((endDate.getTime() - startDate.getTime()) / (1000 * 3600 * 24));
    }


    /**
     * 获取两个时间相差的月份
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 月份
     */
    public static int getMonthSpace(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            return 0;
        }
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(startDate);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(endDate);
        int result = (cal1.get(Calendar.YEAR) - cal2.get(Calendar.YEAR)) * 12 + cal1.get(Calendar.MONTH) - cal2.get(Calendar.MONTH);
        return Math.abs(result);
    }

    /**
     * 北京时间 转换 utc时间
     *
     * @param cstDate
     * @return
     */
    public static Date cstToUtc(Date cstDate) {
        return addHours(cstDate, -8);
    }

    /**
     * 获取1970年第一天的时间
     *
     * @param time
     * @return
     */
    public static Date getTime(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.YEAR, 1970);
        calendar.set(Calendar.MONTH, 0);
        calendar.set(Calendar.DATE, 1);

        return calendar.getTime();
    }


    public static Date parseLocalDateTime(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }


    public static Date getWeekBegin(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayOfWeek == 1) {
            dayOfWeek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayOfWeek);
        return getDateBegin(cal.getTime());
    }

    public static Date getWeekEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getWeekBegin(date));
        cal.add(Calendar.DAY_OF_WEEK, 6);
        Date weekEndSta = cal.getTime();
        return getDateEnd(weekEndSta);
    }


    /**
     * 由出生日期获得年龄
     *
     * @param birthDay 生日
     * @return 年龄
     */
    public static int getAge(Date birthDay) {
        Calendar cal = Calendar.getInstance();
        //获取当前年
        int yearNow = cal.get(Calendar.YEAR);
        //获取当前月
        int monthNow = cal.get(Calendar.MONTH);
        //获取当日
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
        cal.setTime(birthDay);
        //获取出生那年
        int yearBirth = cal.get(Calendar.YEAR);
        //获取出生月
        int monthBirth = cal.get(Calendar.MONTH);
        //获取出生日
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
        //年纪
        int age = yearNow - yearBirth;
        //如果现在的月份小于生日的月份,年龄-1,如果等于出生的月份,日前小于生日日期,年龄-1
        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                if (dayOfMonthNow < dayOfMonthBirth) {
                    age--;
                }
            } else {
                age--;
            }
        }
        return age;
    }

    /**
     * 获取当前时间的开始小时
     *
     * @param time
     * @return
     */
    public static Date getHourStart(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取当前时间的结束小时
     *
     * @param time
     * @return
     */
    public static Date getHourEnd(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 获取当前年开始月份
     *
     * @param time 时间
     * @return
     * @author hw
     * @date 2020/8/8 11:26
     **/
    public static Date getCurrentYearStart(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.DATE, 0);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();

    }

    /**
     * 获取当前年结束月份
     *
     * @param time 时间
     * @return
     * @author hw
     * @date 2020/8/8 11:27
     **/
    public static Date getCurrentYearEnd(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        int year = calendar.get(Calendar.YEAR);
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        return calendar.getTime();
    }

    /**
     * 查看日期是否是今天
     *
     * @param date 日期
     * @return 是否今天
     */
    public static boolean isToday(Date date) {
        if (date == null) {
            return false;
        }
        date = getDateBegin(date);
        Date today = getDateBegin(new Date());
        if (date.getTime() == today.getTime()) {
            return true;
        }
        return false;
    }

    public static Date getWeeks(Integer weeks) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        calendar.add(Calendar.WEEK_OF_YEAR, -weeks);
        return calendar.getTime();
    }

    /**
     * 清除时分秒
     *
     * @param date 日期
     * @return 日期
     */
    public static Date clearTime(Date date) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
        try {
            return sdf.parse(sdf.format(date));
        } catch (ParseException e) {
            logger.warn("清除时分秒失败.", e);
            return date;
        }
    }


    /**
     * 比较两个日期是否同一天
     *
     * @param date  日期
     * @param date1 日期
     * @return 是否同一天
     */
    public static boolean isOnDay(Date date, Date date1) {
        if (date == null || date1 == null) {
            return false;
        }
        return clearTime(date).getTime() == clearTime(date1).getTime();
    }

    /**
     * 比较两个日期是否同一月
     *
     * @param date  日期
     * @param date1 日期
     * @return 是否同一月
     */
    public static boolean isOnMonth(Date date, Date date1) {
        if (date == null || date1 == null) {
            return false;
        }
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(clearTime(date));
        calendar1.set(Calendar.DAY_OF_MONTH, 1);
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(clearTime(date1));
        calendar2.set(Calendar.DAY_OF_MONTH, 1);
        return clearTime(date).getTime() == clearTime(date1).getTime();
    }

    /**
     * @param nowTime   当前时间
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     * @author sunran   判断当前时间在时间区间内
     */
    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 计算时间是周几
     *
     * @param time
     * @return
     */
    public static String getWeek(Date time) {
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        return weekDays[calendar.get(Calendar.DAY_OF_WEEK) - 1];
    }

    /**
     * 获取过去一年的月份 包含当前月
     *
     * @return 过去一年的月份
     */
    public static List<Date> getPastYearMonth() {
        List<Date> list = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        Date date = DateUtil.getMonthBegin(new Date());
        calendar.setTime(date);
        // 一年十二个月
        int months = 12;
        for (int i = 0; i < months; i++) {
            list.add(calendar.getTime());
            calendar.add(Calendar.MONTH, -1);
        }
        list.sort(Date::compareTo);
        return list;
    }

    public static void main(String[] args) throws ParseException {
//        Date minDate = DateUtil.parseDate("2021-09-11 14:00:00", DATE_TIME_FORMAT);
//        Date maxDate = DateUtil.parseDate("2021-09-11 15:00:00", DATE_TIME_FORMAT);
//
//        System.out.println(JSONObject.toJSONString(getDayListOfMinute(minDate, maxDate, 10)));
        List<Date> pastYearMonth = getPastYearMonth();
        for (Date date : pastYearMonth) {
            System.out.println(formatDate(date));
        }
        System.out.println();

        System.out.println(getHourEnd(new Date()));
    }


}
